0.1 Carregamento de um novo conjunto de dados no formato SMART

A primeira função que utilizaremos, carregar_dados_brutos_xlsx(), irá carregar a planilha de dados do SMART em formato excel. Essa função carrega um arquivo do tipo .xlsx e gerar automaticamente o arquivo backup nomeado como dados_brutos_SMART.rds na pasta data-raw. A função seguinte a ser utilizada, gerar_dados_completos_SMART() que irá carregar o arquivo dados_brutos_SMART.rds. Essa função foi escrita para carrega os dados e operar uma série de transformações para devolvê-lo mais próximo ao necessário para conduzir as análises. Como exemplo, utilizaremos o arquivo monitora_masto_aves_SMART.xlsx.

Antes de começar o carregamento dos dados é necessário carregar as funções necessárias utilizando o comando source().

# carregar as funções necessárias
source(here::here("R/carregar_dados_brutos_xlsx.R"))

source(here::here("R/gerar_dados_completos_SMART.R"))

Para carregar a nova base de dados, é importante que ela esteja salva na pasta data-raw do projeto Monitora. Para isso, basta manter a estrutura de pastas do projeto (veja o README do repositório). No corpo da função, deve ser informado o caminho para o arquivo (ex. nome da pasta, data-raw, e o nome do arquivo, monitora_masto_aves_2023_04_04.xlsx).

# carregar a base de dados do Monitora
dados_brutos_SMART <- carregar_dados_brutos_xlsx(
  dados = "data-raw/monitora_masto_aves_SMART.xlsx",
  sheet = 3
)

head(dados_brutos_SMART)
dplyr::glimpse(dados_brutos_SMART)
Rows: 27,940
Columns: 34
$ `CDUC (código da unidade de conservação)`     <dbl> …
$ `Local - Nome da Unidade de Conservação`      <chr> …
$ `Número da Estação Amostral`                  <dbl> …
$ `Nome da EA`                                  <chr> …
$ `Esforço de amostragem tamanho da trilha (m)` <dbl> …
$ `data de início da amostragem`                <dttm> …
$ `data de término da amostragem`               <lgl> …
$ `Ano da amostragem`                           <dbl> …
$ `Estação do ano`                              <chr> …
$ `Horário de início`                           <dttm> …
$ `Horário de término`                          <dttm> …
$ `Tempo de censo`                              <dttm> …
$ `Velocidade (km/h)`                           <dbl> …
$ `Condição Climática/Tempo`                    <chr> …
$ `ID Observadores`                             <lgl> …
$ `ID líder`                                    <lgl> …
$ `Nome dos observadores`                       <chr> …
$ `Nome do líder`                               <lgl> …
$ `ID observação`                               <lgl> …
$ `Número do animal no guia`                    <dbl> …
$ classe                                        <chr> …
$ ordem                                         <chr> …
$ familia                                       <chr> …
$ gênero                                        <chr> …
$ especie                                       <chr> …
$ `nome popular`                                <lgl> …
$ `O que foi identificado`                      <chr> …
$ `Nº animais encontrados`                      <dbl> …
$ `tinha mais?`                                 <lgl> …
$ `distância da trilha (metros)`                <dbl> …
$ `Número da próxima plaqueta`                  <dbl> …
$ `Problema na amostragem?`                     <chr> …
$ Longitude                                     <lgl> …
$ Latitude                                      <lgl> …

Em seguida, usamos a função gerar_dados_completos_SMART().

# gerar dados completos
dados_completos_SMART <- gerar_dados_completos_SMART(dados_brutos_SMART)

head(dados_completos_SMART)
dplyr::glimpse(dados_completos_SMART)
Rows: 26,473
Columns: 20
$ nome_ea             <fct> ana, ana, ana, ana, ana, …
$ n_visitas_repetidas <int> 67, 67, 67, 67, 67, 67, 6…
$ codigo_uc           <dbl> 259, 259, 259, 259, 259, …
$ categoria_uc        <fct> resex, resex, resex, rese…
$ nome_uc             <fct> resex_tapajos_arapiuns, r…
$ nome_uc_abv         <fct> rta, rta, rta, rta, rta, …
$ numero_ea           <dbl> 6, 6, 6, 6, 6, 6, 6, 6, 6…
$ data_amostragem     <dttm> 2015-02-25, 2015-02-25, …
$ estacao             <fct> chuvosa, chuvosa, chuvosa…
$ ano                 <dbl> 2015, 2015, 2015, 2015, 2…
$ esforco_dia         <dbl> 5000, 5000, 5000, 5000, 5…
$ esforco_total       <dbl> 335000, 335000, 335000, 3…
$ nome_sp             <fct> dasyprocta_leporina, maza…
$ nome_sp_abv         <fct> dasy_lepo, maza_sp, dasy_…
$ validacao           <fct> especie, genero, especie,…
$ distancia           <dbl> 10, 5, 0, 3, 3, 5, 12, 18…
$ tamanho_grupo       <dbl> 1, 1, 1, 2, 1, 1, 1, 1, 2…
$ velocidade_km_h     <dbl> 0.5555556, NA, NA, 0.5555…
$ tempo_censo         <drtn> 540 mins, 540 mins, 540 …
$ numero_observadores <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1…

Para garantir a reprodutibilidade dos códigos produzidos em versões atualizadas da base de dados do Monitora, é importante tomar alguns cuidados. O primeiro e mais importante cuidado é manter a consistência dos nomes, da ordem e do número de colunas em versões atualizadas da base de dados do Monitora. Além de carregar os dados, a função carregar_dados_completos() aplica uma série de transformações nas colunas. Seus nomes são alterados, e a essas são atribuídos tipos apropriados (data, caracter, fator, inteiro e numérico), linhas são eliminadas e novas colunas são geradas. Qualquer alteração no número de colunas, nos seus nomes ou na sua ordem levará a um mal funcionamento da função de transformação dos dados.

Outros aspectos importantes incluem:

A partir de agora os dados estão prontos para serem explorados, ou mesmo filtrados e transformados para o formato do pacote Distance para análise de densidade. Por exemplo, filtrar os dados para a UC cujos os dados foram introduzidos a partir do SMART:

# carregar função de filtragem dos dados
source(here::here("R/filtrar_dados.R"))

# filtrar dados por Unidade de Conservação e por espécie
dados_filtrados_SMART <- filtrar_dados(
  dados = dados_completos_SMART,
  nome_ucs = "rds_uatuma"
)

head(dados_filtrados_SMART)
str(dados_filtrados_SMART)
tibble [53 × 20] (S3: tbl_df/tbl/data.frame)
 $ nome_ea            : Factor w/ 73 levels "ana","angelin",..: 41 41 41 41 41 41 41 41 41 41 ...
 $ n_visitas_repetidas: int [1:53] 1 1 1 1 1 1 1 1 1 1 ...
 $ codigo_uc          : num [1:53] NA NA NA NA NA NA NA NA NA NA ...
 $ categoria_uc       : Factor w/ 6 levels "esec","flona",..: 4 4 4 4 4 4 4 4 4 4 ...
 $ nome_uc            : Factor w/ 41 levels "esec_da_terra_do_meio",..: 26 26 26 26 26 26 26 26 26 26 ...
 $ nome_uc_abv        : Factor w/ 39 levels "em","en","esgt",..: 31 31 31 31 31 31 31 31 31 31 ...
 $ numero_ea          : num [1:53] 1 1 1 1 1 1 1 1 1 1 ...
 $ data_amostragem    : POSIXct[1:53], format: "2023-06-14" ...
 $ estacao            : Factor w/ 4 levels "chuvosa","final_de_chuva",..: 3 3 3 3 3 3 3 3 3 3 ...
 $ ano                : num [1:53] 2023 2023 2023 2023 2023 ...
 $ esforco_dia        : num [1:53] 4396 4396 4396 4396 4396 ...
 $ esforco_total      : num [1:53] 4396 4396 4396 4396 4396 ...
 $ nome_sp            : Factor w/ 267 levels "a_louatta_juara",..: 172 198 88 223 92 119 258 86 54 69 ...
 $ nome_sp_abv        : Factor w/ 260 levels "a_lou_juar","abur_cuju",..: 166 192 86 217 90 115 251 84 56 73 ...
 $ validacao          : Factor w/ 5 levels "especie","familia",..: 1 1 3 3 1 3 1 1 1 1 ...
 $ distancia          : num [1:53] NA NA NA NA NA 0 4 8 0 3 ...
 $ tamanho_grupo      : num [1:53] 1 1 2 4 1 1 2 1 2 4 ...
 $ velocidade_km_h    : num [1:53] 24381 24381 24381 24381 24381 ...
 $ tempo_censo        : 'difftime' num [1:53] 259.633333333333 259.633333333333 259.633333333333 259.633333333333 ...
  ..- attr(*, "units")= chr "mins"
 $ numero_observadores: num [1:53] 4 4 4 4 4 4 4 4 4 4 ...

Agora, podemos contar o número de observações validadas:

# carregar a função de contagem das observações validadas
source(here::here("R/contar_n_obs_validadas.R"))

# contar observações validadas ao nível de espécie
n_obs_validadas <- contar_n_obs_validadas(dados_filtrados_SMART)
n_obs_validadas

Vamos selecionar uma espécie da RDS Uatumã para então transformar os dados para o formato de análise do pacote Distance. Primeiro vamos avaliar qual foi a espécie mais abundante:

# carregar a função para contar número de observações por espécie e plotar os dados
source(here::here("R/contar_n_obs_sp.R"))
source(here::here("R/plotar_n_obs_sp_interativo.R"))

# contar o número de observações por espécie
n_obs_sp <- contar_n_obs_sp(dados_filtrados_SMART)
n_obs_sp

# plotar o número de observações por espécie
plotar_n_obs_sp_interativo(n_obs_sp)

A espécie mais abundante foi Crypturellus sp. Vamos filtrar os dados somente para esse espécie:

dados_filtrados_crypt_SMART <- filtrar_dados(
  dados = dados_filtrados_SMART,
  nome_sps = "crypturellus"
)

head(dados_filtrados_crypt_SMART)
str(dados_filtrados_crypt_SMART)
tibble [9 × 20] (S3: tbl_df/tbl/data.frame)
 $ nome_ea            : Factor w/ 73 levels "ana","angelin",..: 41 41 41 41 41 41 41 41 41
 $ n_visitas_repetidas: int [1:9] 1 1 1 1 1 1 1 1 1
 $ codigo_uc          : num [1:9] NA NA NA NA NA NA NA NA NA
 $ categoria_uc       : Factor w/ 6 levels "esec","flona",..: 4 4 4 4 4 4 4 4 4
 $ nome_uc            : Factor w/ 41 levels "esec_da_terra_do_meio",..: 26 26 26 26 26 26 26 26 26
 $ nome_uc_abv        : Factor w/ 39 levels "em","en","esgt",..: 31 31 31 31 31 31 31 31 31
 $ numero_ea          : num [1:9] 1 1 1 1 1 1 1 1 1
 $ data_amostragem    : POSIXct[1:9], format: "2023-06-14" ...
 $ estacao            : Factor w/ 4 levels "chuvosa","final_de_chuva",..: 3 3 3 3 3 3 3 3 3
 $ ano                : num [1:9] 2023 2023 2023 2023 2023 ...
 $ esforco_dia        : num [1:9] 4396 4396 4396 4396 4396 ...
 $ esforco_total      : num [1:9] 4396 4396 4396 4396 4396 ...
 $ nome_sp            : Factor w/ 267 levels "a_louatta_juara",..: 88 88 88 88 88 88 88 88 88
 $ nome_sp_abv        : Factor w/ 260 levels "a_lou_juar","abur_cuju",..: 86 86 86 86 86 86 86 86 86
 $ validacao          : Factor w/ 5 levels "especie","familia",..: 3 3 3 3 3 3 3 3 3
 $ distancia          : num [1:9] NA NA 6 9 13 1 17 1 2
 $ tamanho_grupo      : num [1:9] 2 1 3 3 1 4 2 2 3
 $ velocidade_km_h    : num [1:9] 24381 24381 24381 24381 24381 ...
 $ tempo_censo        : 'difftime' num [1:9] 259.633333333333 259.633333333333 259.633333333333 259.633333333333 ...
  ..- attr(*, "units")= chr "mins"
 $ numero_observadores: num [1:9] 4 4 4 4 4 4 4 4 4

Finalmente, vamos transformar os dados para o formato de análise:

# carregar função de transformação dos dados para o formato do pacote Distance
source(here::here("R/transformar_dados_formato_Distance.R"))

# transformar dados para o formato do pacote Distance
dados_transformados_SMART <- transformar_dados_formato_Distance(dados_filtrados_crypt_SMART)

head(dados_transformados_SMART)
dplyr::glimpse(dados_transformados_SMART)
Rows: 9
Columns: 12
$ Region.Label <fct> rds_uatuma, rds_uatuma, rds_uatu…
$ Area         <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0
$ Sample.Label <fct> na, na, na, na, na, na, na, na, …
$ Effort       <dbl> 4396, 4396, 4396, 4396, 4396, 43…
$ sampling_day <dttm> 2023-06-14, 2023-06-14, 2023-06-…
$ distance     <dbl> NA, NA, 6, 9, 13, 1, 17, 1, 2
$ season       <fct> na, na, na, na, na, na, na, na,…
$ year         <dbl> 2023, 2023, 2023, 2023, 2023, 20…
$ size         <dbl> 2, 1, 3, 3, 1, 4, 2, 2, 3
$ cense_time   <drtn> 259.6333 mins, 259.6333 mins, 25…
$ speed        <dbl> 24381.46, 24381.46, 24381.46, 24…
$ object       <int> 1, 2, 3, 4, 5, 6, 7, 8, 9
LS0tCnRpdGxlOiAiRmx1eG8gZGUgdHJhYmFsaG8gcGFyYSBvIGNhcnJlZ2FtZW50byBkZSBub3ZvcyBkYWRvcyBubyBmb3JtYXRvIFNNQVJUIgphdXRob3I6IAotIEx1Y2lhbmEgRnVzaW5hdHRvIAotIFZpdG9yIEJvcmdlcy1Kw7puaW9yCmRhdGU6IENyaWFkbyBlbSAxNyBkZSBqdWxobyBkZSAyMDIzLCBhdHVhbGl6YWRvIGVtIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgZGUgJUIKICBkZSAlWScpYApvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDUKICAgIHRvY19mbG9hdDogbm8KICAgIG51bWJlcl9zZWN0aW9uOiB5ZXMKICAgIGNvZGVfZm9sZGluZzogc2hvdwotLS0KCiMjICoqQ2FycmVnYW1lbnRvIGRlIHVtIG5vdm8gY29uanVudG8gZGUgZGFkb3Mgbm8gZm9ybWF0byBTTUFSVCoqIAoKQSBwcmltZWlyYSBmdW7Dp8OjbyBxdWUgdXRpbGl6YXJlbW9zLCBgY2FycmVnYXJfZGFkb3NfYnJ1dG9zX3hsc3goKWAsIGlyw6EgY2FycmVnYXIgYSBwbGFuaWxoYSBkZSBkYWRvcyBkbyBTTUFSVCBlbSBmb3JtYXRvIGV4Y2VsLiBFc3NhIGZ1bsOnw6NvIGNhcnJlZ2EgdW0gYXJxdWl2byBkbyB0aXBvIC54bHN4IGUgZ2VyYXIgYXV0b21hdGljYW1lbnRlIG8gYXJxdWl2byAqYmFja3VwKiBub21lYWRvIGNvbW8gYGRhZG9zX2JydXRvc19TTUFSVC5yZHNgIG5hIHBhc3RhIGBkYXRhLXJhd2AuIEEgZnVuw6fDo28gc2VndWludGUgYSBzZXIgdXRpbGl6YWRhLCBgZ2VyYXJfZGFkb3NfY29tcGxldG9zX1NNQVJUKClgIHF1ZSBpcsOhIGNhcnJlZ2FyIG8gYXJxdWl2byBgZGFkb3NfYnJ1dG9zX1NNQVJULnJkc2AuIEVzc2EgZnVuw6fDo28gZm9pIGVzY3JpdGEgcGFyYSBjYXJyZWdhIG9zIGRhZG9zIGUgb3BlcmFyIHVtYSBzw6lyaWUgZGUgdHJhbnNmb3JtYcOnw7VlcyBwYXJhIGRldm9sdsOqLWxvIG1haXMgcHLDs3hpbW8gYW8gbmVjZXNzw6FyaW8gcGFyYSBjb25kdXppciBhcyBhbsOhbGlzZXMuIENvbW8gZXhlbXBsbywgdXRpbGl6YXJlbW9zIG8gYXJxdWl2byBgbW9uaXRvcmFfbWFzdG9fYXZlc19TTUFSVC54bHN4YC4gIAoKQW50ZXMgZGUgY29tZcOnYXIgbyBjYXJyZWdhbWVudG8gZG9zIGRhZG9zIMOpIG5lY2Vzc8OhcmlvIGNhcnJlZ2FyIGFzIGZ1bsOnw7VlcyBuZWNlc3PDoXJpYXMgdXRpbGl6YW5kbyBvIGNvbWFuZG8gYHNvdXJjZSgpYC4KCmBgYHtyfQojIGNhcnJlZ2FyIGFzIGZ1bsOnw7VlcyBuZWNlc3PDoXJpYXMKc291cmNlKGhlcmU6OmhlcmUoIlIvY2FycmVnYXJfZGFkb3NfYnJ1dG9zX3hsc3guUiIpKQoKc291cmNlKGhlcmU6OmhlcmUoIlIvZ2VyYXJfZGFkb3NfY29tcGxldG9zX1NNQVJULlIiKSkKYGBgCgpQYXJhIGNhcnJlZ2FyIGEgbm92YSBiYXNlIGRlIGRhZG9zLCDDqSBpbXBvcnRhbnRlIHF1ZSBlbGEgZXN0ZWphIHNhbHZhIG5hIHBhc3RhIGBkYXRhLXJhd2AgZG8gcHJvamV0byBNb25pdG9yYS4gUGFyYSBpc3NvLCBiYXN0YSBtYW50ZXIgYSBlc3RydXR1cmEgZGUgcGFzdGFzIGRvIHByb2pldG8gKHZlamEgbyBSRUFETUUgZG8gcmVwb3NpdMOzcmlvKS4gTm8gY29ycG8gZGEgZnVuw6fDo28sIGRldmUgc2VyIGluZm9ybWFkbyBvIGNhbWluaG8gcGFyYSBvIGFycXVpdm8gKGV4LiBub21lIGRhIHBhc3RhLCBgZGF0YS1yYXdgLCBlIG8gbm9tZSBkbyBhcnF1aXZvLCBgbW9uaXRvcmFfbWFzdG9fYXZlc18yMDIzXzA0XzA0Lnhsc3hgKS4KCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQojIGNhcnJlZ2FyIGEgYmFzZSBkZSBkYWRvcyBkbyBNb25pdG9yYQpkYWRvc19icnV0b3NfU01BUlQgPC0gY2FycmVnYXJfZGFkb3NfYnJ1dG9zX3hsc3goCiAgZGFkb3MgPSAiZGF0YS1yYXcvbW9uaXRvcmFfbWFzdG9fYXZlc19TTUFSVC54bHN4IiwKICBzaGVldCA9IDMKKQoKaGVhZChkYWRvc19icnV0b3NfU01BUlQpCmRwbHlyOjpnbGltcHNlKGRhZG9zX2JydXRvc19TTUFSVCkKYGBgCgpFbSBzZWd1aWRhLCB1c2Ftb3MgYSBmdW7Dp8OjbyBgZ2VyYXJfZGFkb3NfY29tcGxldG9zX1NNQVJUKClgLiAKCmBgYHtyfQojIGdlcmFyIGRhZG9zIGNvbXBsZXRvcwpkYWRvc19jb21wbGV0b3NfU01BUlQgPC0gZ2VyYXJfZGFkb3NfY29tcGxldG9zX1NNQVJUKGRhZG9zX2JydXRvc19TTUFSVCkKCmhlYWQoZGFkb3NfY29tcGxldG9zX1NNQVJUKQpkcGx5cjo6Z2xpbXBzZShkYWRvc19jb21wbGV0b3NfU01BUlQpCmBgYAoKUGFyYSBnYXJhbnRpciBhIHJlcHJvZHV0aWJpbGlkYWRlIGRvcyBjw7NkaWdvcyBwcm9kdXppZG9zIGVtIHZlcnPDtWVzIGF0dWFsaXphZGFzIGRhIGJhc2UgZGUgZGFkb3MgZG8gTW9uaXRvcmEsIMOpIGltcG9ydGFudGUgdG9tYXIgYWxndW5zIGN1aWRhZG9zLiBPIHByaW1laXJvIGUgbWFpcyBpbXBvcnRhbnRlIGN1aWRhZG8gw6kgKiptYW50ZXIgYSBjb25zaXN0w6puY2lhIGRvcyBub21lcywgZGEgb3JkZW0gZSBkbyBuw7ptZXJvIGRlIGNvbHVuYXMqKiBlbSB2ZXJzw7VlcyBhdHVhbGl6YWRhcyBkYSBiYXNlIGRlIGRhZG9zIGRvIE1vbml0b3JhLiBBbMOpbSBkZSBjYXJyZWdhciBvcyBkYWRvcywgYSBmdW7Dp8OjbyBgY2FycmVnYXJfZGFkb3NfY29tcGxldG9zKClgIGFwbGljYSB1bWEgc8OpcmllIGRlIHRyYW5zZm9ybWHDp8O1ZXMgbmFzIGNvbHVuYXMuIFNldXMgbm9tZXMgc8OjbyBhbHRlcmFkb3MsIGUgYSBlc3NhcyBzw6NvIGF0cmlidcOtZG9zIHRpcG9zIGFwcm9wcmlhZG9zIChkYXRhLCBjYXJhY3RlciwgZmF0b3IsIGludGVpcm8gZSBudW3DqXJpY28pLCBsaW5oYXMgc8OjbyBlbGltaW5hZGFzIGUgbm92YXMgY29sdW5hcyBzw6NvIGdlcmFkYXMuIFF1YWxxdWVyIGFsdGVyYcOnw6NvIG5vIG7Dum1lcm8gZGUgY29sdW5hcywgbm9zIHNldXMgbm9tZXMgb3UgbmEgc3VhIG9yZGVtIGxldmFyw6EgYSB1bSBtYWwgZnVuY2lvbmFtZW50byBkYSBmdW7Dp8OjbyBkZSB0cmFuc2Zvcm1hw6fDo28gZG9zIGRhZG9zLgoKT3V0cm9zIGFzcGVjdG9zIGltcG9ydGFudGVzIGluY2x1ZW06IAoKLSBhIHByZXNlbsOnYSBkZSBkYWRvcyBhdXNlbnRlcyAoYE5BYHMpIHPDo28gYXV0b21hdGljYW1lbnRlIHN1YnN0aXR1aWRhcyBwZWxvIHZhbG9yIGNvcnJldG8gYXBlbmFzIG5hcyBjb2x1bmFzIGBub21lX2VhYCwgYGVzZm9yY29fZGlhYCBlIGB0ZW1wb19zZW5zb2A7CgotIG5vdm9zIGRhZG9zIGRldmVtIHNlciBhZGljaW9uYWRvcyBhIHBsYW5pbGhhIGRlIGRhZG9zIHV0aWxpemFkYSBjb21vIG1vZGVsbyBubyBwcmVzZW50ZSBkb2N1bWVudG87CgotIHNlIG5vdmFzIFVuaWRhZGVzIGRlIENvbnNlcnZhw6fDo28gcGFyYSBhbMOpbSBkYXMgNDEgcHJlc2VudGVzIG5lc3NhIHBsYW5pbGhhIGZvcmVtIGFkaWNpb25hZGFzLCBhIGZ1bsOnw6NvIHBvZGUgZGVpeGFyIGRlIGZ1bmNpb25hci4gTmVzc2UgY2FzbywgZW50cmUgZW0gY29udGF0byBjb20gb3MgZGVzZW52b2x2ZWRvcmVzIHZpYSBlLW1haWw6IHZudGJvcmdlc2pyQGdtYWlsLmNvbTsKCi0gb3Mgbm9tZXMgZG9zIG9ic2VydmFkb3JlcyBkZXZlbSBzZXIgc2VwYXJhZG9zIHBvciAiIGUgIiwgIiBFICIsICIvIiwgIjsiLCBvdSAiIGEgIi4gTm90ZSBxdWUsIHF1YW5kbyBwcmVzZW50ZXMsIG9zIGVzcGHDp29zIHPDo28gaW1wb3J0YW50ZXMgZSBkZXZlbSBzZXIgYXBsaWNhZG9zIHBhcmEgc2VwYXJhw6fDo28gZG9zIG5vbWVzOwoKLSBuYSBjb2x1bmEgYHZhaWxkYWNhb2AgKGNvbHVuYSAiTyBxdWUgZm9pIGlkZW50aWZpY2FkbyIgbmEgcGxhbmlsaGEgb3JpZ2luYWwpIGVzcMOpY2llIGRldmUgc2VyIGlkZW50aWZpY2FkbyBjb21vICJFIiwgImUiLCBvdSAiZXNww6ljaWUiOyBnw6puZXJvIGRldmUgc2VyIGlkZW50aWZpY2FkbyBjb21vICJHIiwgImciLCBvdSAiZ8OqbmVybyI7IGZhbcOtbGlhIGRldmUgc2VyIGlkZW50aWZpY2FkYSBjb21vICJGIjsgZSBvcmRlbSBkZXZlIHNlciBpZGVudGlmaWNhZGEgY29tbyAiTyIuCgpBIHBhcnRpciBkZSBhZ29yYSBvcyBkYWRvcyBlc3TDo28gcHJvbnRvcyBwYXJhIHNlcmVtIGV4cGxvcmFkb3MsIG91ICBtZXNtbyBmaWx0cmFkb3MgZSB0cmFuc2Zvcm1hZG9zIHBhcmEgbyBmb3JtYXRvIGRvIHBhY290ZSBgRGlzdGFuY2VgIHBhcmEgYW7DoWxpc2UgZGUgZGVuc2lkYWRlLiBQb3IgZXhlbXBsbywgZmlsdHJhciBvcyBkYWRvcyBwYXJhIGEgVUMgY3Vqb3Mgb3MgZGFkb3MgZm9yYW0gaW50cm9kdXppZG9zIGEgcGFydGlyIGRvIFNNQVJUOgoKYGBge3J9CiMgY2FycmVnYXIgZnVuw6fDo28gZGUgZmlsdHJhZ2VtIGRvcyBkYWRvcwpzb3VyY2UoaGVyZTo6aGVyZSgiUi9maWx0cmFyX2RhZG9zLlIiKSkKCiMgZmlsdHJhciBkYWRvcyBwb3IgVW5pZGFkZSBkZSBDb25zZXJ2YcOnw6NvIGUgcG9yIGVzcMOpY2llCmRhZG9zX2ZpbHRyYWRvc19TTUFSVCA8LSBmaWx0cmFyX2RhZG9zKAogIGRhZG9zID0gZGFkb3NfY29tcGxldG9zX1NNQVJULAogIG5vbWVfdWNzID0gInJkc191YXR1bWEiCikKCmhlYWQoZGFkb3NfZmlsdHJhZG9zX1NNQVJUKQpzdHIoZGFkb3NfZmlsdHJhZG9zX1NNQVJUKQpgYGAKCkFnb3JhLCBwb2RlbW9zIGNvbnRhciBvIG7Dum1lcm8gZGUgb2JzZXJ2YcOnw7VlcyB2YWxpZGFkYXM6CgpgYGB7cn0KIyBjYXJyZWdhciBhIGZ1bsOnw6NvIGRlIGNvbnRhZ2VtIGRhcyBvYnNlcnZhw6fDtWVzIHZhbGlkYWRhcwpzb3VyY2UoaGVyZTo6aGVyZSgiUi9jb250YXJfbl9vYnNfdmFsaWRhZGFzLlIiKSkKCiMgY29udGFyIG9ic2VydmHDp8O1ZXMgdmFsaWRhZGFzIGFvIG7DrXZlbCBkZSBlc3DDqWNpZQpuX29ic192YWxpZGFkYXMgPC0gY29udGFyX25fb2JzX3ZhbGlkYWRhcyhkYWRvc19maWx0cmFkb3NfU01BUlQpCm5fb2JzX3ZhbGlkYWRhcwpgYGAKClZhbW9zIHNlbGVjaW9uYXIgdW1hIGVzcMOpY2llIGRhIFJEUyBVYXR1bcOjIHBhcmEgZW50w6NvIHRyYW5zZm9ybWFyIG9zIGRhZG9zIHBhcmEgbyBmb3JtYXRvIGRlIGFuw6FsaXNlIGRvIHBhY290ZSBgRGlzdGFuY2VgLiBQcmltZWlybyB2YW1vcyBhdmFsaWFyIHF1YWwgZm9pIGEgZXNww6ljaWUgbWFpcyBhYnVuZGFudGU6CgpgYGB7cn0KIyBjYXJyZWdhciBhIGZ1bsOnw6NvIHBhcmEgY29udGFyIG7Dum1lcm8gZGUgb2JzZXJ2YcOnw7VlcyBwb3IgZXNww6ljaWUgZSBwbG90YXIgb3MgZGFkb3MKc291cmNlKGhlcmU6OmhlcmUoIlIvY29udGFyX25fb2JzX3NwLlIiKSkKc291cmNlKGhlcmU6OmhlcmUoIlIvcGxvdGFyX25fb2JzX3NwX2ludGVyYXRpdm8uUiIpKQoKIyBjb250YXIgbyBuw7ptZXJvIGRlIG9ic2VydmHDp8O1ZXMgcG9yIGVzcMOpY2llCm5fb2JzX3NwIDwtIGNvbnRhcl9uX29ic19zcChkYWRvc19maWx0cmFkb3NfU01BUlQpCm5fb2JzX3NwCgojIHBsb3RhciBvIG7Dum1lcm8gZGUgb2JzZXJ2YcOnw7VlcyBwb3IgZXNww6ljaWUKcGxvdGFyX25fb2JzX3NwX2ludGVyYXRpdm8obl9vYnNfc3ApCmBgYAoKQSBlc3DDqWNpZSBtYWlzIGFidW5kYW50ZSBmb2kgKkNyeXB0dXJlbGx1cyogc3AuIFZhbW9zIGZpbHRyYXIgb3MgZGFkb3Mgc29tZW50ZSBwYXJhIGVzc2UgZXNww6ljaWU6CgpgYGB7cn0KZGFkb3NfZmlsdHJhZG9zX2NyeXB0X1NNQVJUIDwtIGZpbHRyYXJfZGFkb3MoCiAgZGFkb3MgPSBkYWRvc19maWx0cmFkb3NfU01BUlQsCiAgbm9tZV9zcHMgPSAiY3J5cHR1cmVsbHVzIgopCgpoZWFkKGRhZG9zX2ZpbHRyYWRvc19jcnlwdF9TTUFSVCkKc3RyKGRhZG9zX2ZpbHRyYWRvc19jcnlwdF9TTUFSVCkKYGBgCgpGaW5hbG1lbnRlLCB2YW1vcyB0cmFuc2Zvcm1hciBvcyBkYWRvcyBwYXJhIG8gZm9ybWF0byBkZSBhbsOhbGlzZToKCmBgYHtyfQojIGNhcnJlZ2FyIGZ1bsOnw6NvIGRlIHRyYW5zZm9ybWHDp8OjbyBkb3MgZGFkb3MgcGFyYSBvIGZvcm1hdG8gZG8gcGFjb3RlIERpc3RhbmNlCnNvdXJjZShoZXJlOjpoZXJlKCJSL3RyYW5zZm9ybWFyX2RhZG9zX2Zvcm1hdG9fRGlzdGFuY2UuUiIpKQoKIyB0cmFuc2Zvcm1hciBkYWRvcyBwYXJhIG8gZm9ybWF0byBkbyBwYWNvdGUgRGlzdGFuY2UKZGFkb3NfdHJhbnNmb3JtYWRvc19TTUFSVCA8LSB0cmFuc2Zvcm1hcl9kYWRvc19mb3JtYXRvX0Rpc3RhbmNlKGRhZG9zX2ZpbHRyYWRvc19jcnlwdF9TTUFSVCkKCmhlYWQoZGFkb3NfdHJhbnNmb3JtYWRvc19TTUFSVCkKZHBseXI6OmdsaW1wc2UoZGFkb3NfdHJhbnNmb3JtYWRvc19TTUFSVCkKYGBgCgo=